#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <libgen.h>
#include <string>

#include <QtGui>

#include "PopupUtilities.hpp"
#include "PopupSettings.hpp"
#include "PopupOSAL.hpp"

using namespace std;
using namespace utilities;
using namespace Popup;

//==============================================================================
// GUI utilities
//==============================================================================

void utilities::showError(const QString & p_text, QWidget *p_parent)
{
  QMessageBox msgBox(QMessageBox::NoIcon, QObject::tr("Popup - Erreur"),
		     p_text, QMessageBox::Ok, p_parent);
  QPixmap _pixmap(":/images/popup_fuckyouborder.png");
  msgBox.setIconPixmap(_pixmap);
  msgBox.exec();
}
//----------------------------------------------------------

void utilities::showWarning(const QString & p_text, QWidget *p_parent)
{
  QMessageBox msgBox(QMessageBox::Warning, QObject::tr("Attention"),
		     p_text, QMessageBox::Ok, p_parent);
  msgBox.exec();
}
//----------------------------------------------------------

bool utilities::confirm(const QString & p_text, QWidget *p_parent)
{
  QMessageBox msgBox(QMessageBox::NoIcon, QObject::tr("Confirmation"),
             p_text, QMessageBox::Ok|QMessageBox::Cancel, p_parent);
  QPixmap _pixmap(":/images/popup_wakeup.png");
  msgBox.setIconPixmap(_pixmap);
  return (msgBox.exec() == QMessageBox::Ok);
}

//==============================================================================
// File selection
//==============================================================================

void utilities::selectFileToTextEdit(QLineEdit *p_edit,
				     QWidget *p_parent,
				     const QString & p_title,
				     const QString & p_filter,
				     const QString & p_default)
{
  QString _default = p_edit->text();
  if (p_default.length() > 0)
  {
    _default = p_default;
  }
  QString _fileName = QFileDialog::getOpenFileName(p_parent, p_title,
						   _default, p_filter);
  if (!_fileName.isEmpty())
  {
    p_edit->setText(_fileName);
  }
}
//----------------------------------------------------------

void utilities::selectDirToTextEdit(QLineEdit *p_edit,
				    QWidget *p_parent,
				    const QString & p_title)
{
  QString _dirName = QFileDialog::getExistingDirectory(p_parent, p_title,
						       p_edit->text());
  if (!_dirName.isEmpty())
  {
    p_edit->setText(_dirName);
  }
}

//==============================================================================
// Resource extraction
//==============================================================================

bool utilities::extractResource(const QString & p_rcname,
                                const QString & p_destfile)
{
  return (QFile::exists(p_destfile) ||
          QFile::copy(p_rcname, p_destfile));
}

//==============================================================================
// Filetypes management
//==============================================================================

bool utilities::isSupportedVideo(const char *p_filename)
{
  const char *_ext = strrchr(p_filename, '.');
  if (_ext != NULL)
  {
    _ext++;
    
    if ((strcasecmp("avi",_ext) == 0) ||
	(strcasecmp("mov",_ext) == 0) ||
	(strcasecmp("wmv",_ext) == 0) ||
	(strcasecmp("mpg",_ext) == 0) ||
	(strcasecmp("mp2",_ext) == 0) ||
	(strcasecmp("mp3",_ext) == 0) ||
	(strcasecmp("mp4",_ext) == 0))
    {
      return true;
    }
  }
  return false;
}
//----------------------------------------------------------

bool utilities::isSupportedImage(const char *p_filename)
{
  static QList<QByteArray> _supportedImages = QImageReader::supportedImageFormats();
  QList<QByteArray>::iterator _it;
  const char *_ext = strrchr(p_filename, '.');

  if (_ext != NULL)
  {
    _ext++;
    for (_it = _supportedImages.begin();
	 _it != _supportedImages.end();
	 _it++)
    {
      if (strcasecmp(_it->data(), _ext) == 0)
      {
	return true;
      }
    }
  }
  return false;
}
//----------------------------------------------------------

bool utilities::isSupportedImage(const string & p_filename)
{
  return isSupportedImage(p_filename.c_str());
}
//----------------------------------------------------------

bool utilities::isSupportedVideo(const string & p_filename)
{
  return isSupportedVideo(p_filename.c_str());
}

//==============================================================================
// Filesystem management
//==============================================================================

bool utilities::createDirectory(const string & p_path)
{
  if (!PopupUtils::mkdir(p_path)) {
    QString _errmsg = QObject::tr("Failed to create directory ") +
      p_path.c_str() + ".";
    showError(_errmsg);
    return false;
  }
  else
  {
    return true;
  }
}

//==============================================================================
// URL/Media management
//==============================================================================

bool utilities::openUrl(const string & p_url)
{
  bool _rc = false;
  QString _browser = PopupSettings::instance()->browser();
  bool _ignorefailure = false;

#ifdef _WINDOWS
  if ((_browser.indexOf("iexplore", 0, Qt::CaseInsensitive) == 0) || 
      (_browser.indexOf("explorer", 0, Qt::CaseInsensitive) == 0))
  {
    _ignorefailure = true;
  }
#endif
  if ((QFile::exists(_browser) == false) && (_ignorefailure == false))
  {
    QString _errmsg;
    _errmsg = QObject::tr("Cannot find such internet browser:");
    _errmsg += "\n(" + _browser + ")\n --> ";
    _errmsg += QObject::tr("Failed to open URL ") + p_url.c_str();
    showError(_errmsg);
  }
  else
  {
    QStringList _url;
    _url << p_url.c_str();
    QProcess::startDetached(_browser, _url);
    _rc = true;
  }

  return _rc;
}
//----------------------------------------------------------

bool utilities::openMedia(const string & p_media)
{
  bool _rc = false;
  QString _media(p_media.c_str());
  
  // If file doesn't exist, we assume it is an URL!
  if (!QFile::exists(_media))
  {
    _rc = openUrl(p_media);
  }
  else
  {
    if (isSupportedVideo(p_media.c_str()) == true)
    {
      QString _player = PopupSettings::instance()->videoPlayer();
      if (!QFile::exists(_player))
      {
	QString _errmsg;
	_errmsg = QObject::tr("Cannot find such video player:");
	_errmsg += "\n(" + _player + ")\n --> ";
	_errmsg += QObject::tr("Failed to open media ") + _media;
	showError(_errmsg);
      }
      else
      {
	QStringList _args;
	_args << _media;
	QProcess::startDetached(_player, _args);
	_rc = true;
      }
    }
    else
    {
      // In all other case, we delegate opening of the media
      // to the internet browser, which will very probably
      // be able to handle it!
      _rc = openUrl(p_media);
    }
  }

  return _rc;
}
//----------------------------------------------------------

bool utilities::openImage(const string & p_image)
{
  bool _rc = false;
  QString _image(p_image.c_str());
  
  // If file doesn't exist, we assume it is an URL!
  if (!QFile::exists(_image))
  {
    _rc = openUrl(p_image);
  }
  else
  {
    QString _viewer = PopupSettings::instance()->imageViewer();
    if (!QFile::exists(_viewer))
    {
      QString _errmsg;
      _errmsg = QObject::tr("Cannot find such image viewer:");
      _errmsg += "\n(" + _viewer + ")\n --> ";
      _errmsg += QObject::tr("Failed to open image ") + _image;
      showError(_errmsg);
    }
    else
    {
      QStringList _args;
      _args << _image;
      _rc = QProcess::startDetached(_viewer, _args);
    }
  }
  
  return _rc;
}

QString utilities::modeToString(UserMode p_mode) {
  switch (p_mode) {
    case POPUP_MODE_DEFAULT:  return "default";
    case POPUP_MODE_PROMPT:   return "prompt";
    case POPUP_MODE_TEXTONLY: return "textonly";
    case POPUP_MODE_MUTED:    return "muted";
    default:                  return "splotch";
  }
}

UserMode utilities::modeFromString(QString p_mode) {
  if (p_mode.compare("default") == 0) {
    return POPUP_MODE_DEFAULT;
  } else  if (p_mode.compare("prompt") == 0) {
    return POPUP_MODE_PROMPT;
  } else if (p_mode.compare("textonly") == 0) {
    return POPUP_MODE_TEXTONLY;
  } else if (p_mode.compare("muted") == 0) {
    return POPUP_MODE_MUTED;
  } else {
    return POPUP_MODE_DEFAULT;
  }
}

QImage utilities::createImageWithOverlay(const QImage & baseImage,
                                         const QImage & overlayImage,
                                         const QImage & overlayImage2)
{
  QImage imageWithOverlay = QImage(baseImage.size(),
                                   QImage::Format_ARGB32_Premultiplied);
  QPainter painter(&imageWithOverlay);
  painter.setCompositionMode(QPainter::CompositionMode_Source);
  painter.fillRect(imageWithOverlay.rect(), Qt::transparent);
  painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
  painter.drawImage(0, 0, baseImage);
  painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
  painter.drawImage(0, 0, overlayImage);
  if (!overlayImage2.isNull()) {
    painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
    painter.drawImage(0, 0, overlayImage2);
  }
  painter.end();
  return imageWithOverlay;
}
